#include "dominion.h"
#include "dominion_helpers.h"
#include "rngs.h"
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "testHelper.c"

#define MAX_CARDS 16
#define MIN_PLAYERS 2
#define MAX_PLAYERS 4
#define MODULUS 2147483647

int checkEndTurn(struct gameState *testState) {
  int i, functionError, player;
  struct gameState controlState;

  memcpy (&controlState, testState, sizeof(struct gameState));

  functionError = endTurn(testState);

  /* SIMULATE THE FUNCTION EFFECT */
  player = controlState.whoseTurn;
  for(i = 0; i < controlState.handCount[player]; i++){
    controlState.discard[player][controlState.discardCount[player]++] = controlState.hand[player][i];//Discard
    controlState.hand[player][i] = -1;
  }
  controlState.handCount[player] = 0;

  if(player < (controlState.numPlayers - 1)){
    controlState.whoseTurn = player + 1; //increment player
  }
  else{
    controlState.whoseTurn = 0; //go back to first player
  }

  controlState.outpostPlayed = 0;
  controlState.phase = 0;
  controlState.numActions = 1;
  controlState.coins = 0;
  controlState.numBuys = 1;
  controlState.playedCardCount = 0;
  controlState.handCount[controlState.whoseTurn] = 0;

  //next player draws five cards
  for(i = 0; i < 5; i++){
    drawCard(controlState.whoseTurn, &controlState);
  }
  //update money
  updateCoins(controlState.whoseTurn, &controlState, 0);

  /* Assert that the function was called safely in the test state */
  assert(functionError == 0);

  /* test to see if both the states are the same */
  if(memcmp(&controlState, testState, sizeof(struct gameState)) == 0){
    return 0;
  }
  else{
    gameStateDiff(&controlState, testState);
    return 1;
  }
}

int main () {
  int i, j, n, numPlayers, seed, success, failure;
  int k[10] = {adventurer, council_room, feast, gardens, mine,
	       remodel, smithy, village, baron, great_hall};
  struct gameState G;
  
  printf ("\n***TESTING END TURN***\n");

  PutSeed(floor(Random() * MODULUS));
  success = 0;
  failure = 0;

  for (n = 0; n < 2000; n++) {
    /* Fill the Game State with garbage */
    for (i = 0; i < sizeof(struct gameState); i++) {
      ((char*)&G)[i] = floor(Random() * 256);
    }
    //initialize new game
    numPlayers = floor(Random() * PLAYER_RANGE) + 2;
    seed = floor(Random() * 1000);
    initializeGame(numPlayers, k, seed, &G);
    for (i = 0; i < numPlayers; i++){
      /* give each player a deck of random size */
      G.deckCount[i] = floor(Random() * MAX_DECK) + 5; //enough cards to draw from
      /* give each player a discard deck of random size */
      G.discardCount[i] = floor(Random() * MAX_DECK);
      /* give each player a hand of random size */
      G.handCount[i] = floor(Random() * MAX_HAND);
      /* fill each players' hand with random cards */
      for (j = 0; j < G.handCount[i]; j++){
	G.hand[i][j] = (Random() * (treasure_map + 1));
      }
    }

    if(checkEndTurn(&G) == 0){ //run test
      success++;
    }
    else{
      failure++;
    }
  }

  printf ("\n***TESTS COMPLETE***\n***SUMMARY\n***Successful Tests: %d\n***Failed Tests: %d\n\n", success, failure);  
  return 0;
}
